Skip to content

feat: stackbilt classify command — zero-cost intent classification#8

Merged
stackbilt-admin merged 10 commits into
mainfrom
feat/classify-command
Jun 12, 2026
Merged

feat: stackbilt classify command — zero-cost intent classification#8
stackbilt-admin merged 10 commits into
mainfrom
feat/classify-command

Conversation

@stackbilt-admin

Copy link
Copy Markdown
Member

Summary

  • Adds stackbilt classify <intention> as a new CLI command
  • Zero network, zero inference, sub-millisecond — pure heuristic pattern matching
  • Detects scaffold pattern, confidence, traits (route_shape/verification/dispatch), quality profile, CF bindings, and tier
  • Supports --format json for agent/script consumption
  • Shape is forward-compatible with @stackbilt/scaffold-core/classify for the build#4 swap once charter#213 lands

Example

$ stackbilt classify "multi-tenant SaaS API with Stripe billing"

  Pattern:     workers-saas
  Confidence:  high
  Traits:      route_shape=rest, verification=none, dispatch=resource-router
  Quality:     tenant, billing
  Bindings:    d1
  Tier 2:      recommended

Test plan

  • 13 unit tests covering all 8 patterns, binding detection, verification detection, confidence levels, tier assignment, and JSON serialisation
  • All 28 repo tests passing (npm test)
  • TypeScript builds clean (npm run build)

Closes #3

🤖 Generated with Claude Code

stackbilt-admin and others added 9 commits June 12, 2026 05:19
Implements `stackbilt classify <intention>` backed by inline heuristics.
Pure pattern-matching, zero network, zero inference, sub-millisecond.
Produces pattern, confidence, traits, quality profile, bindings, and tier.
Supports --format json. Forward-compatible shape for build#4 swap to
@stackbilt/scaffold-core/classify once charter#213 lands.

Closes #3

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Add @stackbilt/core to package.json dependencies (sanitizeInput import)
- Add comment separator for rest-api pattern rule in PATTERN_RULES
- Tighten rest-api signal to require framework keywords (express/fastify/hono)
  so generic API intentions fall through to workers-api instead
- Fix durable-objects binding regex: `do` bare word was too broad,
  now requires `durable.?objects?` full form
- Scaffold architect.ts stub (placeholder for governance-only implementation)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Rewrites architect.ts from a network-calling build command into a
zero-network, zero-inference governance document generator that:

- Takes a plain-text intention argument
- Runs classifyScaffoldIntention heuristics (reuses classify.ts)
- Emits threat model (STRIDE-shaped, pattern + binding specific),
  ADR-001 (pattern + bindings rationale), and ADR-002 (compliance
  domains — PCI/GDPR/HIPAA/SOC2 — only when detected)
- Includes a testPlan field in --format json output
- Supports --format json with keys { threatModel, adr001, adr002, testPlan }
- Is already wired in cli.ts as the architect subcommand
- TODO(build#4): swap template functions for @stackbilt/scaffold-core/governance
  once charter#218 ships

Updates auth-wiring.test.ts: old tests verified EngineClient wiring which no
longer applies; replaced with tests confirming governance-only contract
(no network call, no auth required, exits 0).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Bug: stackbilt run wrote files but never updated .charter/last-build.json,
so `stackbilt scaffold` following `run` would fail with
"No cached build found. Run stackbilt architect first."

Root cause: run.ts converted BuildResult → ScaffoldResult for rendering
but discarded the raw BuildResult that scaffold.ts needs (.scaffold dict,
.stack, .seed keys).

Fix:
- Capture rawBuildResult on the non-gateway (engine) path before conversion
- Call cacheBuildResult(rawBuildResult, configPath) after writing files, on
  both the JSON and text output paths
- Cache path is path.join(configPath, 'last-build.json'), matching scaffold.ts
- Gateway path (ScaffoldResult shape) is a different contract — not cached,
  scaffold.ts will surface a clear error if attempted

Adds scaffold-cache.test.ts: 5 contract tests verifying the
read/write path, JSON round-trip, mkdir -p behaviour, and shared cache key.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
cli.ts rewrite:
- --format json is now parsed once at the top level and propagated via
  options.format to all commands (login, architect, classify, run, scaffold)
- --version / -v prints the version from package.json and exits 0
- --help / -h at top level prints full usage; per-command --help prints
  command-specific usage with flags and examples
- parseGlobalFlags() extracts format/help/version before dispatching,
  eliminating duplicated arg parsing in each command
- Version is read from package.json at runtime via createRequire (single SoT)
- No command given now shows help rather than erroring

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…fold

- Create packages/scaffold-core shim (pending charter#220 npm publication)
  - classify.ts: canonical heuristic classifier, exports classify()
  - governance.ts: threat model + ADR templates, exports buildGovernance()
  - scaffold.ts: file set generator, exports buildScaffold()
  - index.ts: barrel re-export of full API surface
- classify.ts: replace local heuristics with classify() from @stackbilt/scaffold-core;
  classifyScaffoldIntention() is now a thin delegation wrapper (all tests pass unchanged)
- architect.ts: replace inline template functions with buildGovernance() from
  @stackbilt/scaffold-core; remove TODO(build#4) comment
- scaffold.ts: wire buildScaffold() as the local fallback when no cached build exists;
  accepts positional intention or --intention flag; existing cache path is unchanged
- package.json: add @stackbilt/scaffold-core dependency (file: until charter#220 lands)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…@stackbilt/scaffold-core@1.0.0

Removes the vendored packages/scaffold-core copy; classify.ts and architect.ts
now import from the published npm package. classify.ts re-exports ClassifyResult,
PatternName, QualityProfile from the package. architect.ts uses buildScaffold()
directly. Tests rewritten for the real API shape: numeric confidence, flat
traits[], QualityProfile boolean fields. 31/31 tests green.

Closes stackbilt-build#3, #4, #5, #6

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Removes buildScaffold(intention, classifyResult) — classifyResult is not
ScaffoldOptions. Switches pattern access to classification.pattern. Drops
non-existent tier and nextSteps fields. Build clean, 31/31 tests green.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ld.json

Standardises on { intention, pattern, classification, governance, files?, createdAt }.
architect writes the cache after buildScaffold() (no files — scaffold generates on demand).
run writes for both gateway and engine paths using the same shape.
scaffold.ts reads new shape (files[]), architect cache (no files → generates), and
legacy BuildResult (scaffold dict) for backward compat. 33/33 tests green.

Closes #7

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@stackbilt-admin stackbilt-admin merged commit 143fec7 into main Jun 12, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat: stackbilt classify command — zero-cost intent classification

1 participant